package com.cherrypt.api.core.aspect;

import com.cherrypt.api.common.enums.LogEnum;
import com.cherrypt.api.common.exception.TipException;
import com.cherrypt.api.core.util.IPUtils;
import com.cherrypt.api.model.dto.UserDto;
import com.cherrypt.api.model.vo.LoginVo;
import com.cherrypt.api.model.vo.RegisterVo;
import com.cherrypt.api.model.vo.ResetPassVo;
import com.cherrypt.api.model.vo.SendResetPassEmailVo;
import com.cherrypt.api.core.service.LogService;
import com.cherrypt.api.core.util.JwtUtils;
import com.cherrypt.api.core.util.LogUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author intent
 * @date 2019/7/23 11:02
 * @about <link href='http://zzyitj.xyz/'/>
 */
@Aspect
@Component
public class AuthAspect {
    private static final Logger logger = LoggerFactory.getLogger(AuthAspect.class);

    @Autowired
    private LogService logService;

    @Pointcut("execution(* com.cherrypt.api.core.controller.AuthController.login(..))")
    public void login() {
    }

    @Pointcut("execution(* com.cherrypt.api.core.controller.AuthController.register(..))")
    public void register() {
    }

    @Pointcut("execution(* com.cherrypt.api.core.controller.AuthController.sendResetPassEmail(..))")
    public void sendResetPassEmail() {
    }

    @Pointcut("execution(* com.cherrypt.api.core.controller.AuthController.resetPass(..))")
    public void resetPass() {
    }

    @Pointcut("execution(* com.cherrypt.api.core.controller.AuthController.logout(..))")
    public void logout() {
    }

    @Pointcut("execution(* com.cherrypt.api.core.controller.AuthController.activation(..))")
    public void activation() {
    }

    /**
     * 返回通知
     *
     * @param joinPoint
     * @param result
     */
    @AfterReturning(value = "login() || register() || sendResetPassEmail() || resetPass()", returning = "result")
    public void authLog(JoinPoint joinPoint, ResponseEntity result) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            int uid = 0;
            LogEnum logEnum = LogEnum.NULL;
            // 处理登录日志
            if (joinPoint.getArgs()[0] instanceof LoginVo) {
                UserDto userDto = (UserDto) result.getBody();
                if (userDto != null) {
                    uid = userDto.getUid();
                }
                logEnum = LogEnum.LOGIN;
            } else if (joinPoint.getArgs()[0] instanceof RegisterVo) {
                // 处理注册日志
                logEnum = LogEnum.REGISTER;
            } else if (joinPoint.getArgs()[0] instanceof SendResetPassEmailVo) {
                // 处理发送重置密码邮件日志
                logEnum = LogEnum.SEND_RESET_PASS_EMAIL;
            } else if (joinPoint.getArgs()[0] instanceof ResetPassVo) {
                // 处理重置密码日志
                logEnum = LogEnum.RESET_PASS;
            }
            LogUtils.writeLog(logService, uid, logEnum, joinPoint.getArgs()[0].toString(), request);
        }
    }

    @AfterReturning(value = "logout()", returning = "result")
    public void logoutLog(JoinPoint joinPoint, ResponseEntity result) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            try {
                int uid = JwtUtils.getUserIdFromRequest(request);
                LogUtils.writeLog(logService, uid, LogEnum.LOGOUT, "", request);
            } catch (TipException e) {
                logger.error("用户注销时获取uid错误, ip: " + IPUtils.getIpAddr(request), e);
            }
        }
    }

    @AfterReturning(value = "activation()", returning = "result")
    public void activationLog(JoinPoint joinPoint, ResponseEntity result) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            String code = (String) joinPoint.getArgs()[0];
            LogUtils.writeLog(logService, 0, LogEnum.ACTIVATION, "激活码: " + code, request);
        }
    }
}
